<!DOCTYPE HTML>
<html>
	<head>
		<title>Future Imperfect by HTML5 UP</title>
		<meta charset="utf-8" />
		<meta name="viewport" content="width=device-width, initial-scale=1" />
		<style>
	.modal_body{
		margin: 1em;
		height: 80%;
	}
	.modal_left{float: left;margin:0 0 0 1em;
		width: 590px;}
	.modal_right{
		float:left;
		margin:0 2em;
		border:1px solid #A9A9A9 ;
		overflow: auto;
		width: 590px;
				}

</style>

		<link rel="stylesheet" href="assets/css/bootstrap.min.css" />
		<link rel="stylesheet" href="assets/css/blogMain.css" />
		

	</head>
	<body>
			<div id="wrapper">

				<!-- Header -->
					<header id="header">
						<h1><a href="../template/inner_index.html">Internal Network</a></h1>
						<nav class="links">
							<ul>
								<li><a href="../template/inner_index.html">内网首页</a></li>
								<li><a href="publicBlog.html">公共博客</a></li>
								<li><a href="resource.html">资源夹</a></li>
								<li><a href="question.html">技术问答</a></li>
								<li><a href="index.html">实验室介绍页</a></li>
							</ul>
						</nav>
					</header>

				
					

				<!-- Main -->
					<div id="main">

						<!-- Post -->
							<article class="post">
								<header>
									<div class="title">
										<h2 id="Title"><a >通知标题</a></h2>
<!--										<p id="brief">通知简介（没有可删除）</p>-->
									</div>
									<div class="meta">
										<time class="published" datetime="2015-11-01">2017/10/10</time>
										<a href="#" class="author"><span class="name">Pasca</span><img src="assets/img/pasca.jpg" alt="" /></a>
									</div>
								</header>
<!--								<a  class="image featured"><img src="assets/img/pic01.jpg" alt="" /></a>-->
								<p id="artical">
									这里是通知内容balabalbalabala
								</p>
								<footer>
									<!--以下修改触发，修改后删除下面这个button即可-->
									<!--<button id="change" data-toggle="modal" data-target="#myModal">
										修改内容
									</button>-->
									<!--以上为修改触发，修改后删除下面这个button即可-->
									
									<!--编译界面-->
									<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" >
										<div class="modal-dialog" style="width: 90%;margin: 2%;">
											<div class="modal-content" style="width: 88em;">
												<div class="modal-header" style="height: 3em;">
													<button type="button" class="close" data-dismiss="modal" aria-hidden="true" style="height: 1em;width: 1em;">
													×
													</button>
												
												</div>
												<!--标题-->
												<div class="modal_body">
													<div class="modal_left">
													<textarea id="text-input_1" class="modal_left" oninput="this.editor.update()" style="height: 35px;" cols="80"> **单例类懒汉式线程安全问题**</textarea>
													</div>
												
													<div  class="modal_right" style="height: 35px;">
														<p id="preview_1" ></p>
													</div>
													<div class="clearfix"></div>
												</div>
												<!--简介-->
												<!--<div class="modal_body">
													<div class="modal_left">
													<textarea id="text-input_2" class="modal_left" oninput="this.editor.update()" style="height: 90px;" cols="80">请根据 **Markdown格式** 输入**概要**.</textarea>
													</div>
												
													<div  class="modal_right" style="height: 90px;">
														<p id="preview_2" ></p>
													</div>
													<div class="clearfix"></div>
												</div>-->
												<!--主题内容-->
												<div class="modal_body">
													<div class="modal_left">
													<textarea id="text-input_2" class="modal_left" oninput="this.editor.update()" style="height: 453px;" cols="80">
鄙渣渣最近在看多线程，在看线程安全问题的时候，不论是学习视频中强调，还是网上搜的单例类、同步、线程安全的面试题中，都有单例类懒汉式线程安全问题。然后又搜了搜，发现有大牛博客上面写了怎么处理懒汉式线程安全问题，却没有说明理由，所以渣渣我结合自己体会写一下。

先小小的介绍一下，单例类是什么
单例类是一种设计思想
简单的基本思想：私有化结构体，通过判断建立的实例是否为空来判断是否能创建对象。使获取对象的途径不是经过结构体，而是通过定义的get函数。

构建单例类的三个基本：
1.只能有一个实例
2.单例类本身必须要建立这个实例
3.要给其他其他对象提供这一实例

单例类有有两个主流格式，饿汉式和懒汉式，实例代码如下：

饿汉式：

	class Single
	{
	  private static final Single f = new Single();
	  private Single(){};
	  public static Single get()
	    {
	        return f;
	    }
	}
	
	  public class Demo {
	  public static void main(String[] args) {
	        Single f =Single.get();  //因为饿汉式在一开始就建立的对象，所以这里只要通过get方法获取引用变量就可以了
	  }
	}
懒汉式：

	class Singleton
    {
    private Singleton(){}     //私有化结构体
    private static Singleton single;   //建立一个变量缓存创建的实例
    public static Singleton get()        //用来判断是否建立对象
    {
    if (single == null)
    {
        single =new Singleton();
    }
     return single;
    }
    }

    public class person
    {
    public static void main(String[] args)
    {
        Singleton f = Singleton.get();    //获取对象不通过结构体，而是通过get方法
    }
    }				
饿汉式因为在一开始就建立了一个静态对象，所以线程天生安全。
既然饿汉式这么简洁，还线程天生安全，为什么要弄懂懒汉式呢？

因为
面试考的
基本上都是懒汉式

懒汉式为什么线程不安全？

	class Singleton
    {
    private Singleton(){}     
    private static Singleton single;   
    public static Singleton get()        
    {
    //1.当有例如A、B、C等多个线程同时进入时
       if (single == null)  
    {
        //--》A
        //--》B
        //--》C
        single =new Singleton();
        //2.则会建立多次对象
    }
     return single;
    }
    }
    public class person
    {
    public static void main(String[] args)
    {
        Singleton f = Singleton.get();  
    }
    }
建立多次对象，这是单例类构造中不被允许的。所以存在线程安全问题。
线程安全用同步解决，但如果简单的同步，会使效率变低很多，ex：

	class Single
    {
    private static  Single f = null;
    private Single(){};
    public static Single get()
    {
        //每一次线程进入，都要对是否持有锁进行判断，效率偏低
            synchronized(Single.class)
            {
            if(f==null)
            f = new Single();
            }
        return f;
    }
    }
    public class Demo {
    public static void main(String[] args) {
        Single f =Single.get();
    }
    }
就如代码注释中所写，不论时间先后，每一个线程试图进入时，都要对是否持有锁进行判断，效率偏低。

PS。锁就是锁旗标，也有叫“监视器”的，在我看的视频教学中，讲师将其称之为锁，很形象，就这么叫了。具体请见我的另一片文章 java.关于线程同步 。

所以就有了双重判断的格式用来提高效率：

	class Single
    {
    private static  Single f = null;
    private Single(){};
    //4.后续的C线程进入后
    public static Single get()
    {
        //4.C线程将在这里被拦截，无法进入
        //1.如果有A B两个线程同时进入了
        if(f==null)
             //2.--》A
            // 2.--》B
            synchronized(Single.class)
            {
            //3.只有一个线程能获取锁
            //3.--》A
            if(f==null)
            //3.当A线程执行完之后，f就不为空了，当之后的B进入的时候，即使B持有锁，也不会进行对象的建立了
            f = new Single();
            }
        return f;
    }
    }

    public class Demo {
    public static void main(String[] args) {
        Single f =Single.get();
    }
    }
双重判定使第一个进入的线程执行完之后，两个if判断都将返还false，之后尝试进入的线程在if那一关就会停下，不必每个线程都要判断是否持有锁，在一定程度上提高的效率。

最后附加饿汉式线程安全的几个简单的问题
1.懒汉式和饿汉式的区别：懒汉式存在延迟加载
2.懒汉式的延迟加载有没有问题：有，如果多线程访问，会存在线程的安全问题
3.怎么解决：用同步解决，但用一些同步代码块和同步函数都稍微有些低效，用双重判定的形式，能在一定程度上解决低效问题。
4.加同步的时候，用的锁是哪一个：该类所属的字节码文件对象

可能写的不够形象精确。。。。但渣渣已经尽力了。如果有路过的大神发现哪个地方写的不对，还望指正。

以上。
													</textarea>
													</div>
												
													<div  class="modal_right" style="height: 453px;">
														<p id="preview_2" ></p>
													</div>
													<div class="clearfix"></div>
												</div>
											
												<div class="modal-footer">
													<button  data-dismiss="modal" >
													提交更改
													</button>
												</div>
												
											</div>
										</div>
									</div>
									<!--编译界面-->
								</footer>
							
							</article>

					

						
					</div>

<!-- Sidebar -->
					<section id="sidebar">

						<!-- Intro -->
							<section id="intro">
								<header>
									<h2>Public Blog</h2>
									<p> The fire burns high <br/>when everybody adds wood to it </p>
								</header>
							</section>



						<!-- Posts List -->
							<section>
<ul class="posts">
									<h2>同类博文</h2>
									<li>
										<article>
											<header>
												<h3><a href="blog1.html">关于线程同步的几个知识点</a></h3>
												<time class="published" datetime="2015-10-20">2017/10/11</time>
											</header>
											<a href="#" class="image"><img src="assets/img/pasca.jpg" alt="" /></a>
										</article>
									</li>
									<li>
										<article>
											<header>
												<h3><a href="blog3.html">JAVA继承特点的小总结</a></h3>
												<time class="published" datetime="2015-10-15">2017/10/12</time>
											</header>
											<a href="#" class="image"><img src="assets/img/pasca.jpg" alt="" /></a>
										</article>
									</li>
									<li>
										<article>
											<header>
												<h3><a href="blog4.html">页面渲染&&影响渲染速度的两个因素</a></h3>
												<time class="published" datetime="2015-10-08">2017/10/15</time>
											</header>
											<a href="#" class="image"><img src="assets/img/pasca.jpg" alt="" /></a>
										</article>
									</li>
									<li>
										<article>
											<header>
												<h3><a href="blog5.html">if与switch的小区别</a></h3>
												<time class="published" datetime="2015-10-08">2017/10/21</time>
											</header>
											<a href="#" class="image"><img src="assets/img/pasca.jpg" alt="" /></a>
										</article>
									</li>

								</ul>
							</section>



						<!-- Footer -->
							<section id="footer">

								<p class="copyright">&copy;Made by 实验室前端组 </p>
							</section>

					</section>
			</div>
			

		<!-- Scripts -->
			<script type="text/javascript" src="assets/js/jquery2.0.min.js" ></script>
			<script src="assets/js/main.js"></script>
			<script type="text/javascript" src="assets/js/bootstrap.min.js" ></script>
			<script type="text/javascript" src="assets/js/markdown.js" ></script>
			<script>
				function Editor(input,preview_1,preview_2){  //将input中的内容赋予preview
					this.update=function(){
						preview_1.innerHTML=markdown.toHTML(input.value);
						preview_2.innerHTML=markdown.toHTML(input.value);
					};
					input.editor=this;
					this.update();
				}				
				var retId =function(id){return document.getElementById(id);};//作用为返回ID的对象
			new Editor(retId("text-input_1"),retId("preview_1"),retId("Title"));
			new Editor(retId("text-input_2"),retId("preview_2"),retId("artical"));

			</script>

	</body>
</html>